package social.hub.oauth.scribe;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

import social.hub.oauth.OAuthServiceConfig;
import social.hub.oauth.OAuthToken;
import social.hub.oauth.OAuthServiceConfig.OAuthVersion;
import social.hub.oauth.scribe.ScribeServiceProvider;
import social.hub.util.Utils;

public class ITScribeServiceProvider_OAuth1a {

	private ScribeServiceProvider	provider;
	private OAuthServiceConfig		serviceConfig;

	@Before
	public void setUp() throws Exception {

		serviceConfig = new OAuthServiceConfig();

		serviceConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken");
		serviceConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
		serviceConfig.setAuthorizeUrl("https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token={requestToken}");

		serviceConfig.setApiKey("www.amigon.com.br");
		serviceConfig.setApiSecret("43iELZZbcbn/m3lWpUQIZljA");
		serviceConfig.setCallbackUrl("https://www.teste.com.br/requestCallback");
		serviceConfig.setScope("http://orkut.gmodules.com/social");

		serviceConfig.setVersion(OAuthVersion.V_1a);

		provider = new ScribeServiceProvider(serviceConfig);

	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testGetAccessToken() throws IOException {

		WebDriver driver = new FirefoxDriver();

		String username = "usuarioteste1@ymail.com";
		String password = "senhateste1";

		// autorizar manualmente no browser...
		OAuthToken requestToken = provider.getRequestToken();
		String authorizationUrl = provider.getAuthorizationUrl(requestToken);

		driver.get(authorizationUrl);

		WebElement usernameInput = driver.findElement(By.id("Email"));
		usernameInput.sendKeys(username);

		WebElement passwordInput = driver.findElement(By.id("Passwd"));
		passwordInput.sendKeys(password);

		usernameInput.submit();

		WebElement allowSubmit = driver.findElement(By.id("allow"));

		allowSubmit.click();

		String resultUrl = driver.getCurrentUrl();

		Map<String, String> parans = montarParametros(resultUrl);

		OAuthToken accessToken = provider.getAccessToken(requestToken, parans);

		assertNotNull(accessToken);
		assertNotNull(accessToken.getToken());
		assertNotNull(accessToken.getSecret());
		
		System.out.println(accessToken.getToken());
		System.out.println(accessToken.getSecret());

		driver.close();

	}

	@Test
	public void testGetAuthorizationUrl() {

		OAuthToken requestToken = provider.getRequestToken();

		String expectedUrl = "https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token="
				+ Utils.encode(requestToken.getToken());

		String authorizationUrl = provider.getAuthorizationUrl(requestToken);

		assertNotNull(requestToken.getToken());
		assertNotNull(requestToken.getSecret());

		assertEquals(expectedUrl, authorizationUrl);

	}

	@Test
	public void testGetRequestToken() {

		OAuthToken requestToken = provider.getRequestToken();

		assertNotNull(requestToken.getToken());
		assertNotNull(requestToken.getSecret());

	}

	@Test
	public void testGetServiceConfig() {

		OAuthServiceConfig result = provider.getServiceConfig();

		assertSame(serviceConfig, result);

	}

	private Map<String, String> montarParametros(String resultUrl) {

		Map<String, String> parans = new HashMap<String, String>();

		String queryString = resultUrl.substring(resultUrl.indexOf("?") + 1, resultUrl.length());

		String[] strings = queryString.split("&");

		for (String string : strings) {
			String[] paran = string.split("=");
			String key = paran[0];
			String value = paran[1];
			parans.put(key, value);
		}

		return parans;

	}

}
